/*
 * @Author: your name
 * @Date: 2021-06-18 14:33:38
 * @LastEditTime: 2021-06-27 16:10:59
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \totiao\src\utils\request.js
 */
import axios from 'axios'
import { Toast } from 'vant'
import store from '../store/index'
// 导入路由模块
import router from '../router/index.js'
// console.log(store)

// 调用 axios.create() 方法，创建 axios 的实例对象
const request = axios.create({
  // 请求根路径
  baseURL: 'http://www.liulongbin.top:8000'
})

// 拦截器的挂载,一定要放到request实例创建之后
// 由于我们在项目中是基于request实例对象发送的请求,因此,拦截器一定要挂载到request,而不是axios!!!!!!!!

// 添加请求拦截器
// 在请求拦截器的第一个function中,形参config就是每次请求时候的配置选项
request.interceptors.request.use(
  function (config) {
    // 在发送请求之前做些什么
    // 展示loading效果
    Toast.loading({
      message: '加载中...',
      loadingType: 'spinner',
      overlay: true,
      duration: 0 // 防止自动关闭
    })

    // 从vuex中获取token的值
    const tokenStr = store.state.tokenInfo.token
    if (tokenStr) {
      // 只有tokenStr的值存在,才有必要挂载到请求头上  config
      config.headers.Authorization = 'Bearer ' + tokenStr
    }
    // console.log(config)
    return config
  },
  function (error) {
    // 对请求错误做些什么
    // 隐藏loading效果
    Toast.clear()
    return Promise.reject(error)
  }
)

// 添加响应拦截器
request.interceptors.response.use(
  function (response) {
    // 对响应数据做点什么
    Toast.clear()
    return response
  },
  async function (error) {
    // 对响应错误做点什么
    Toast.clear()
    // 方法1
    // 判断一下失败的status状态码是否为401
    // // 如果是401证明token过期导致的有权限的接口调用失败
    // console.dir(error)
    // if (error.response.state === 401) {
    //   // 证明token过期了
    //   // 1.强制跳转登录页
    //   router.replace('/login?pie=' + router.currentRoute.fullPath)
    //   // 2.强制清空vuex和localStorage中的数据
    //   store.commit('cleanState')
    // }

    // 方法2
    // 从vuex中获取refresh_token的值
    const refreshToken = store.state.tokenInfo.refresh_token
    // 2. 判断是否为 token 过期
    if (error.response.status === 401 && refreshToken) {
      // token 过期
      console.log('换取token的值')
      try {
        // 3.1 TODO: 发起请求，根据 refresh_token 重新请求一个有效的新 token
        const { data: res } = await axios({
          method: 'PUT',
          url: 'http://www.liulongbin.top:8000/v1_0/authorizations',
          headers: {
            Authorization: 'Bearer ' + refreshToken
          }
        })
        console.log(res)
        console.log('token换取成功')
        // 用新token替换到vuex和localStorage中的旧token
        store.commit('updateTokenInfo', { token: res.data.token, refresh_token: refreshToken })
        // 继续完成上次失败的请求
        // 1.要知道method是什么
        // 2.url地址?
        // 3.请求方式,参数?
        // console.log(error)
        return request(error.config)
      } catch {
        // 只要能够执行到catch中的代码,证明token和 refresh_token 都过期了
        store.commit('/login?pre' + router.currentRoute.fullPath)
      }
    }
    return Promise.reject(error)
  }
)

export default request
